﻿using System.Text;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;
using Zero.WebAPI.Framework.Helper.Encrypt;

namespace 请求响应加密.Middle
{
    public class EncryptionHandle
    {
        private readonly IConfiguration _configuration;
        private readonly IMemoryCache _memoryCache;
        private readonly RequestDelegate _next;

        public EncryptionHandle(IConfiguration configuration, IMemoryCache memoryCache, RequestDelegate next)
        {
            _configuration = configuration;
            _memoryCache = memoryCache;
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            HttpRequest request = context.Request;
            HttpResponse response = context.Response;

            // 判断是否需要解密
            bool reqFlag = false;
            string isEncryp = request.Headers["Encrypt"].ToString();
            if (!string.IsNullOrEmpty(isEncryp))
                reqFlag = bool.Parse(isEncryp);

            bool isLogined = context.Request.Headers.TryGetValue("Authorization", out StringValues token);
            if (!isLogined)   // 用户未登录，这里直接放行到后续的中间件
            {
                await _next(context);
                return;
            }

            bool isKeySet = _memoryCache.TryGetValue(token, out object aesKey);

            if (reqFlag)
            {
                // 对请求的数据进行解密
                // 将加密数据从请求体中提取出来
                // 把提取出的数据进行解密处理
                // 将解密后的数据重新放到请求体中
                if (isKeySet)
                {
                    string methodType = request.Method.ToLower();
                    if (methodType == "get")
                    {
                        QueryString val = request.QueryString;
                        if (val.HasValue)
                        {
                            string rawParam = EncryptHelper.AESDecrypt(val.Value.Substring(1), aesKey.ToString());
                            request.QueryString = new QueryString($"?{rawParam}");
                        }
                    }
                    else if (methodType == "post")
                    {
                        using (StreamReader stream = new StreamReader(request.Body))
                        {
                            // 读取发送的base64编码的加密数据
                            string val = await stream.ReadToEndAsync();
                            val = val.Replace("\"", "");
                            string rawData = EncryptHelper.AESDecrypt(val, aesKey.ToString());
                            StringContent content = new StringContent(rawData);
                            request.Body = await content.ReadAsStreamAsync();
                        }
                    }
                }
                else
                {
                    throw new Exception("未设置通信密钥，或通信密钥已经过期，请重新登录");
                }

            }

            // 判断返回数据是否需要加密
            bool respflag = _configuration.GetValue<bool>("Encrypt");

            if (respflag)
            {
                // 提取出响应的原始数据
                // 对原始数据进行加密处理
                // 将加密后的数据重新设置到响应体中
                // 先将流换成可读写的流，默认的响应流是只能写入的，不能读取
                if (isKeySet)
                {
                    using (MemoryStream mstream = new MemoryStream())
                    {
                        Stream stream = response.Body;
                        response.Body = mstream;
                        // 执行下一个中间件内容
                        await _next(context);

                        using (var reader = new StreamReader(response.Body))
                        {
                            response.Body.Seek(0, SeekOrigin.Begin);
                            //response.Body.Position = 0;
                            string res = await reader.ReadToEndAsync();
                            if (string.IsNullOrEmpty(res))
                                return;

                            response.Headers.Add("Encrypt", new Microsoft.Extensions.Primitives.StringValues("true"));
                            response.Headers.Add("Access-Control-Expose-Headers", new Microsoft.Extensions.Primitives.StringValues("*"));
                            string encrypVal = EncryptHelper.AESEncrypt(res, aesKey.ToString());
                            byte[] respBytes = Encoding.UTF8.GetBytes(encrypVal);
                            response.ContentLength = respBytes.Length;
                            await stream.WriteAsync(respBytes, 0, respBytes.Length);
                            response.Body = stream;
                        }
                    }
                }
            }
            else
            {
                await _next(context);
            }
        }

        private HttpContent CreateStringContent(string content)
        {
            // 创建一个 StringContent，但不设置 Content-Type
            var stringContent = new StringContent(content, Encoding.UTF8);
            stringContent.Headers.ContentType = null; // 清除 Content-Type
            return stringContent;
        }
    }
}

// multipart/form-data类型的请求参数
/*
 -----bsfkdkafsdjfksdfsdkfksdkfdskfksd---
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=name

张三
-----bsfkdkafsdjfksdfsdkfksdkfdskfksd---
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=age

19
-----bsfkdkafsdjfksdfsdkfksdkfdskfksd---
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=dataUser

{"uid":"000001000002","Name":"张三","Gender":"男","Age":21,"Email":"123456@qq.com","Password":"123456","Address":"山东省济宁市金乡县","CreateDate":"2024-12-16 9:29"}
-----bsfkdkafsdjfksdfsdkfksdkfdskfksd-----
 */

// ------------------ 标准类型 ------------------------
/*
 ------WebKitFormBoundaryNhJ2fyaktyKAFeMd
Content-Disposition: form-data; name="name"

张三
------WebKitFormBoundaryNhJ2fyaktyKAFeMd
Content-Disposition: form-data; name="age"

19
------WebKitFormBoundaryNhJ2fyaktyKAFeMd
Content-Disposition: form-data; name="dataUser"

{"uid":"000001000002","Name":"张三","Gender":"男","Age":21,"Email":"123456@qq.com","Password":"123456","Address":"山东省济宁市金乡县","CreateDate":"2024-12-16 9:29"}
------WebKitFormBoundaryNhJ2fyaktyKAFeMd--

 */

/*
 -----bsfkdkafsdjfksdfsdkfksdkfdskfksd---
Content-Disposition: form-data; name=name

张三
-----bsfkdkafsdjfksdfsdkfksdkfdskfksd---
Content-Disposition: form-data; name=age

19
-----bsfkdkafsdjfksdfsdkfksdkfdskfksd---
Content-Disposition: form-data; name=dataUser

{"uid":"000001000002","Name":"张三","Gender":"男","Age":21,"Email":"123456@qq.com","Password":"123456","Address":"山东省济宁市金乡县","CreateDate":"2024-12-16 9:29"}
-----bsfkdkafsdjfksdfsdkfksdkfdskfksd-----

 */